﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DatabaseLayer;
using System.Data.Objects;
using System.Globalization;
using System.Windows.Controls.Primitives;

namespace DatabaseManager
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SpeakupEntities m_context;
        Schedule m_schedule;

        bool IgnoreSelectionChanged = false;

        public MainWindow()
        {
            InitializeComponent();
            m_context = DatabaseContextFactory.Create();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            {
                var classTypes = from ct in m_context.ClassTypes
                                 select ct;

                ObjectResult result = ((ObjectQuery)classTypes).Execute(MergeOption.AppendOnly);
                ClassTypesListView.DataContext = result;
            }

            {
                var levels = from ct in m_context.Levels
                             select ct;

                ObjectResult result = ((ObjectQuery)levels).Execute(MergeOption.AppendOnly);
                LevelsListView.DataContext = result;
            }

            {
                var weeks = from ct in m_context.Weeks
                            select ct;

                ObjectResult result = ((ObjectQuery)weeks).Execute(MergeOption.AppendOnly);
                WeeksListView.DataContext = result;
            }
        }

        public void RefreshSchedules()
        {
            var subjects = from o in m_context.Schedule
                           orderby o.ClassTypeId ascending, o.LevelId ascending, o.WeekId ascending
                           select o;

            ObjectResult result = ((ObjectQuery)subjects).Execute(MergeOption.AppendOnly);
            ScheduleListView.DataContext = result;
        }

        private void ScheduleListView_Loaded(object sender, RoutedEventArgs e)
        {
            RefreshSchedules();
        }

        private void NextListItem(Selector selector)
        {
            if (selector.Items.Count == 0) return;

            int index = selector.SelectedIndex;
            if (index < 0)
            {
                selector.SelectedIndex = 0;
                return;
            }

            if (index == selector.Items.Count - 1)
            {
                selector.SelectedIndex = 0;
            }
            else
            {
                selector.SelectedIndex = index + 1;
            }
        }

        private void NextClassType_Click(object sender, RoutedEventArgs e)
        {
            NextListItem(ClassTypesListView);
        }

        private void NextLevel_Click(object sender, RoutedEventArgs e)
        {
            NextListItem(LevelsListView);
        }

        private void NextWeek_Click(object sender, RoutedEventArgs e)
        {
            NextListItem(WeeksListView);
        }

        private void NextTheme()
        {
            if (ClassTypesListView.SelectedIndex < 0 || LevelsListView.SelectedIndex < 0 || WeeksListView.SelectedIndex < 0)
            {
                ClassTypesListView.SelectedIndex = 0;
                LevelsListView.SelectedIndex = 0;
                WeeksListView.SelectedIndex = 0;
                return;
            }

            NextListItem(WeeksListView);
            if (WeeksListView.SelectedIndex != 0)
            {
                return;
            }

            NextListItem(LevelsListView);
            if (LevelsListView.SelectedIndex != 0)
            {
                return;
            }

            NextListItem(ClassTypesListView);
        }

        private void AddOrUpdateTheme()
        {
            ClassType classType = (ClassType)ClassTypesListView.SelectedItem;
            Level level = (Level)LevelsListView.SelectedItem;
            Week week = (Week)WeeksListView.SelectedItem;

            if (classType == null || level == null || week == null)
            {
                return;
            }

            Schedule curTheme = (from n in m_context.Schedule
                                 where n.ClassTypeId == classType.Id && n.LevelId == level.Id && n.WeekId == week.Id
                                 select n).FirstOrDefault();


            if (curTheme == null)
            {
                Schedule schedule = new Schedule();
                schedule.ClassTypeId = classType.Id;
                schedule.LevelId = level.Id;
                schedule.WeekId = week.Id;
                schedule.Theme = UpdatedThemeTextBlock.Text;

                m_context.Schedule.AddObject(schedule);
            }
            else
            {
                curTheme.Theme = UpdatedThemeTextBlock.Text;
            }

            m_context.SaveChanges();
            RefreshSchedules();
        }

        private void RemoveTheme()
        {
            ClassType classType = (ClassType)ClassTypesListView.SelectedItem;
            Level level = (Level)LevelsListView.SelectedItem;
            Week week = (Week)WeeksListView.SelectedItem;

            if (classType == null || level == null || week == null)
            {
                return;
            }

            Schedule curTheme = (from n in m_context.Schedule
                                 where n.ClassTypeId == classType.Id && n.LevelId == level.Id && n.WeekId == week.Id
                                 select n).FirstOrDefault();


            if (curTheme != null)
            {
                m_context.DeleteObject(curTheme);
                m_context.SaveChanges();
                RefreshSchedules();
            }
        }

        private void UpdateActionButtons()
        {
            bool enableUpdateButtons = false;
            if (m_schedule == null)
            {
                enableUpdateButtons = (UpdatedThemeTextBlock.Text.Length != 0);
            }
            else
            {
                enableUpdateButtons = (UpdatedThemeTextBlock.Text != m_schedule.Theme);
            }

            UpdateAndNextThemeButton.IsEnabled = enableUpdateButtons;
            UpdateThemeButton.IsEnabled = enableUpdateButtons;

            UpdateAndNextThemeButton.IsDefault = enableUpdateButtons;
            NextThemeButton.IsDefault = !enableUpdateButtons;        
        }

        private void NextTheme_Click(object sender, RoutedEventArgs e)
        {
            NextTheme();
        }

        private void UpdateThenNextTheme_Click(object sender, RoutedEventArgs e)
        {
            IgnoreSelectionChanged = true;
            AddOrUpdateTheme();
            IgnoreSelectionChanged = false;
            
            NextTheme();
        }

        private void UpdateTheme_Click(object sender, RoutedEventArgs e)
        {
            AddOrUpdateTheme();
            ThemeKeySelectionChanged();
        }

        private void RemoveTheme_Click(object sender, RoutedEventArgs e)
        {
            RemoveTheme();
            ThemeKeySelectionChanged();
        }

        //if listview was forced to unselect the only selected item,
        //this functions then forces it to reselect last selected item
        private void UndoUnselect(ListView listView, SelectionChangedEventArgs e)
        {
            if (listView.SelectedIndex < 0)
            {
                if (e.RemovedItems.Count > 0)
                {
                    listView.SelectedItem = e.RemovedItems[0];
                }
            }
        }

        private void ThemeKeySelectionChanged()
        {
            if (IgnoreSelectionChanged) return;

            ClassType classType = (ClassType)ClassTypesListView.SelectedItem;
            Level level = (Level)LevelsListView.SelectedItem;
            Week week = (Week)WeeksListView.SelectedItem;

            if (classType == null || level == null || week == null)
            {
                return;
            }

            m_schedule = (from n in m_context.Schedule
                         where n.ClassTypeId == classType.Id && n.LevelId == level.Id && n.WeekId == week.Id
                         select n).FirstOrDefault();

            if (m_schedule!= null)
            {
                //TODO:
                CurrentThemeTextBox.Background = Brushes.LightGreen;
                CurrentThemeTextBox.Text = m_schedule.Theme;
                UpdatedThemeTextBlock.Text = m_schedule.Theme;

                UpdateAndNextThemeButton.Content = "Update/Next";
                UpdateThemeButton.Content = "Update";
                RemoveThemeButton.IsEnabled = true;

                ScheduleListView.SelectedItem = m_schedule;
            }
            else
            {
                //TODO:
                CurrentThemeTextBox.Background = Brushes.LightPink;
                CurrentThemeTextBox.Text = "N/A (theme is not created yet)";
                UpdatedThemeTextBlock.Text = "";

                UpdateAndNextThemeButton.Content = "Add/Next";
                UpdateThemeButton.Content = "Add";
                RemoveThemeButton.IsEnabled = false;

                ScheduleListView.SelectedItem = null;
            }

            UpdatedThemeTextBlock.CaretIndex = UpdatedThemeTextBlock.Text.Length;            

            UpdateActionButtons();
        }

        private void ClassTypesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreSelectionChanged) return;

            UndoUnselect((ListView)sender, e);
            ThemeKeySelectionChanged();
        }

        private void LevelsListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreSelectionChanged) return;

            UndoUnselect((ListView)sender, e);
            ThemeKeySelectionChanged();
        }

        private void WeeksListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreSelectionChanged) return;

            UndoUnselect((ListView)sender, e);
            ThemeKeySelectionChanged();
        }

        private void UpdatedThemeTextBlock_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateActionButtons();    
        }
        
        private void ScheduleListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreSelectionChanged) return;

            ListView listView = (ListView)sender;

            if (listView.SelectedItem == null) return;

            Schedule schedule = (Schedule)listView.SelectedItem;
            listView.ScrollIntoView(schedule);

            IgnoreSelectionChanged = true;
            ClassTypesListView.SelectedItem = schedule.ClassType;
            LevelsListView.SelectedItem = schedule.Level;
            WeeksListView.SelectedItem = schedule.Week;
            IgnoreSelectionChanged = false;

            ThemeKeySelectionChanged();
        }
    }
}
